// +----------------------------------------------------------------------
// | 描述: 数据处理工具
// +----------------------------------------------------------------------
// | 作者: cleverstone
// +----------------------------------------------------------------------
// |
// +----------------------------------------------------------------------

/**
 * Code Assist
 * @type {{numberSub(*=, *): (*|number), camelcaseToHyphen(*): string, oneOf(*, *): boolean, firstUpperCase(*): string, numberMul(*, *): number, unitInto(*=): *, typeOf(*=): *, deepCopy(*=): *, numberAdd(*, *): number, numberDiv(*, *): number}}
 */
module.exports = {
    /**
     * 数据类型校验
     * @param obj
     * @return {*}
     */
    typeOf(obj) {
        const toString = Object.prototype.toString
        const map = {
            '[object Boolean]': 'boolean',
            '[object Number]': 'number',
            '[object String]': 'string',
            '[object Function]': 'function',
            '[object Array]': 'array',
            '[object Date]': 'date',
            '[object RegExp]': 'regExp',
            '[object Undefined]': 'undefined',
            '[object Null]': 'null',
            '[object Object]': 'object'
        };
        return map[toString.call(obj)]
    },

    /**
     * 字符串首字母大写
     * @param str
     * @return {string}
     */
    firstUpperCase(str) {
        return str.toString()[0].toUpperCase() + str.toString().slice(1)
    },

    /**
     * 小驼峰转下划线
     * @param str
     * @return {string}
     */
    camelcaseToHyphen(str) {
        return str.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase()
    },

    /**
     * 判断数组或对象中是否存在指定值
     * @param value
     * @param validList
     * @return {boolean}
     */
    oneOf(value, validList) {
        for (let i = 0; i < validList.length; i++) {
            if (value === validList[i]) {
                return true
            }
        }

        return false
    },

    /**
     * clone数据
     * @param data
     * @return {*}
     */
    deepCopy(data) {
        const t = typeOf(data)
        let o

        if (t === 'array') {
            o = []
        } else if (t === 'object') {
            o = {}
        } else {
            return data
        }

        if (t === 'array') {
            for (let i = 0; i < data.length; i++) {
                o.push(deepCopy(data[i]))
            }
        } else if (t === 'object') {
            for (let i in data) {
                o[i] = deepCopy(data[i])
            }
        }

        return o
    },

    /**
     * 高精度加法
     * @param n1
     * @param n2
     * @return {number}
     */
    numberAdd(n1, n2) {
        let r1,
            r2,
            m
        try {
            r1 = n1.toString().split('.')[1].length
        } catch (e) {
            r1 = 0
        }

        try {
            r2 = n2.toString().split('.')[1].length
        } catch (e) {
            r2 = 0
        }

        m = Math.pow(10, Math.max(r1, r2))
        let a = parseInt(n1 * m)
        let b = parseInt(n2 * m)

        return (a + b) / m
    },

    /**
     * 高精度减法
     * @param n1
     * @param n2
     * @return {*|number}
     */
    numberSub(n1, n2) {
        return this.numberAdd(n1, -n2)
    },

    /**
     * 高精度乘法
     * @param n1
     * @param n2
     * @return {number}
     */
    numberMul(n1, n2) {
        let m = 0,
            s1 = n1.toString(),
            s2 = n2.toString()
        try {
            m += s1.split('.')[1].length
        } catch (e) {
        }

        try {
            // m是累加结果
            m += s2.split('.')[1].length
        } catch (e) {
        }

        return Number(s1.replace('.', '')) * Number(s2.replace('.', '')) / Math.pow(10, m)
    },

    /**
     * 高精度除法
     * @param n1
     * @param n2
     * @return {number}
     */
    numberDiv(n1, n2) {
        let r1,
            r2,
            m
        try {
            r1 = n1.toString().split('.')[1].length
        } catch (e) {
            r1 = 0
        }

        try {
            r2 = n2.toString().split('.')[1].length
        } catch (e) {
            r2 = 0
        }

        m = Math.pow(10, Math.max(r1, r2))
        let a = parseInt(n1 * m)
        let b = parseInt(n2 * m)

        return a / b
    },

    /**
     * 数据单位转换
     * @param number
     * @return {*}
     */
    unitInto(number) {
        if (!number) return '-'
        let value = isNaN(Number(number)) ? 0 : Number(number)

        let z = 10000,              // 万
            y = 100000000,          // 亿
            q = 100000000000,       // 千亿
            w = 1000000000000       // 万亿
        if (value >= z && value < y) {
            value = (value / z).toFixed(2) + '万'
        } else if (value >= y && value < q) {
            value = (value / y).toFixed(2) + '亿'
        } else if (value >= q && value < w) {
            value = (value / q).toFixed(2) + '千亿'
        } else if (value >= w) {
            value = (value / w).toFixed(2) + '万亿'
        }

        return value
    }
}
